package s.k.gui.webtest.css;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Properties;

import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;

import s.k.gui.webtest.asserttools.SKSimpleCheckTool;
import s.k.gui.webtest.basetools.SKBaseTools;
import s.k.gui.webtest.basetools.SKPropertiesTool;
import s.k.gui.webtest.constvalue.ConstValue;
import s.k.gui.webtest.element.Element;
import s.k.gui.webtest.element.Image;
import s.k.gui.webtest.exceptions.SKFailedError;
import s.k.gui.webtest.log.MyLogger;

public class SKCSSTools {
	private static MyLogger logger = MyLogger.getLogger(SKBaseTools.class);
	private static String commProConf = "css_comman_property_config.properties";
	private static String imgProConf = "css_img_property_config.properties";
	private static Properties cssCommanPropertiesConfig;
	private static Properties cssImgPropertiesConfig;

	/** ��ʼ��css�����ļ� */
	private static void initCssConfigs() {
		cssCommanPropertiesConfig = SKPropertiesTool
				.getPropertyInfo(ConstValue.CSSPROPERTIESCONFIGDIR + "\\"
						+ commProConf);
		cssImgPropertiesConfig = SKPropertiesTool
				.getPropertyInfo(ConstValue.CSSPROPERTIESCONFIGDIR + "\\"
						+ imgProConf);
	}

	static {
		initCssConfigs();
		SKBaseTools.configLogProperties();
	}

	/**
	 * ָ��Ԫ�ر��ش洢��css������Ϣ�������ڷ���property�ļ���Ϣ�������ڷ���null
	 * 
	 * @param element
	 *            ָ����holmosԪ��
	 * @return ָ��Ԫ�ر��ش洢��css������Ϣ
	 * */
	private static Properties getCSSValueFromLocal(Element element) {
		String cssFilePath = ConstValue.CSSPROPERTIESDIR + "\\"
				+ element.getFullName() + ".properties";
		return SKPropertiesTool.getPropertyInfo(cssFilePath);
	}

	/**
	 * �ڱ���û��css�����ļ�������£�����ҳ�������������ȡImg����Ԫ��������Ϣ
	 * */
	private static Properties getImgCssValues(Element element) {
		Properties imgCssProperties = new Properties();
		Iterator<Object> imgCssKeyIterator = cssImgPropertiesConfig.keySet()
				.iterator();
		if (element.isExist()) {
			while (imgCssKeyIterator.hasNext()) {
				String cssKey = (String) imgCssKeyIterator.next();
				if (SKPropertiesTool.getBoolean(cssImgPropertiesConfig, cssKey)) {
					imgCssProperties.put(cssKey, element.getElement()
							.getCssValue(cssKey));
				}
			}
		}
		return imgCssProperties;
	}

	/**
	 * �ڱ���û��css�����ļ�������£�����ҳ�������������ȡ��ͨ����Ԫ��������Ϣ
	 * */
	private static Properties getCommCssValues(Element element) {
		Properties comCssProperties = new Properties();
		Iterator<Object> imgCssKeyIterator = cssCommanPropertiesConfig.keySet()
				.iterator();
		if (element.isExist()) {
			while (imgCssKeyIterator.hasNext()) {
				String cssKey = (String) imgCssKeyIterator.next();
				if (SKPropertiesTool.getBoolean(cssCommanPropertiesConfig,
						cssKey)) {
					comCssProperties.put(cssKey, element.getElement()
							.getCssValue(cssKey));
				}
			}
		}
		return comCssProperties;
	}

	/**
	 * �ڱ���û��css�����ļ�������£�����ҳ�������������ȡԪ��������Ϣ
	 * */
	private static Properties getCssValuesFromEngine(Element element) {
		if (element instanceof Image) {
			return getImgCssValues(element);
		}
		return getCommCssValues(element);
	}

	/**
	 * �ӱ����Ԫ��element�����еĴ洢��css���ԣ����û�еĻ�����ô���´ӽ����ϻ�ȡ��<br>
	 * Ȼ������ļ������ҽ����ļ��洢��holmos���ָ����λ��,�����ڣ���ֱ�ӻ�ȡ
	 * 
	 * @param element
	 *            holmos���ָ����Ԫ��
	 * */
	public static Properties getCSSValues(Element element) {
		Properties cssProperties = getCSSValueFromLocal(element);
		if (cssProperties != null)
			return cssProperties;
		cssProperties = getCssValuesFromEngine(element);
		SKPropertiesTool.savePropertiesFile(cssProperties,
				ConstValue.CSSPROPERTIESDIR + "\\" + element.getFullName(),
				element.getFullName() + "css������Ϣ");
		return cssProperties;
	}

	/**
	 * ��ȡָ��Ԫ�ص�ָ��css���ԣ��������л�ȡ
	 * 
	 * @param element
	 *            ָ����Ԫ��
	 * @param ָ������������
	 * @return ��ȡ����������Ϣ
	 * */
	public static String getCssValue(Element element, String cssValueKey) {
		if (element.isExist()) {
			return element.getCSSValue(cssValueKey);
		}
		return null;
	}

	/**
	 * ��ȡ����ָ��Ԫ���б��λ����Ϣ�����Ͻǵ�λ��
	 * */
	private ArrayList<Point> getLocations(ArrayList<Element> elements) {
		ArrayList<Point> locations = new ArrayList<Point>();
		for (Element element : elements) {
			locations.add(element.getLocation());
		}
		return locations;
	}

	/**
	 * ��ȡ����ָ��Ԫ���б�Ĵ�С��Ϣ
	 * */
	private ArrayList<Dimension> getSizes(ArrayList<Element> elements) {
		ArrayList<Dimension> sizes = new ArrayList<Dimension>();
		for (Element element : elements) {
			sizes.add(element.getSize());
		}
		return sizes;
	}

	/**
	 * У���Ԫ���б��Ƿ��ϱ߽����
	 * 
	 * @param elements
	 *            ��У���Ԫ��
	 * */
	public void assertTopAlign(ArrayList<Element> elements) {
		ArrayList<Point> locations = getLocations(elements);
		for (int i = 1; i < locations.size(); i++) {
			if (locations.get(i).x != locations.get(0).x) {
				StringBuilder message = new StringBuilder("�ϱ߽����У��ʧ��:\n");
				for (int j = 0; j < locations.size(); j++) {
					message.append(elements.get(j).getComment() + "���ϱ߽�λ��:"
							+ locations.get(j).x + "\n");
				}
				throw new SKFailedError(message.toString());
			}
		}
		logger.info("�ϱ߽�У��ɹ�!");
	}

	/**
	 * У���Ԫ���б��Ƿ���߽����
	 * 
	 * @param elements
	 *            ��У���Ԫ��
	 * */
	public void assertLeftAlign(ArrayList<Element> elements) {
		ArrayList<Point> locations = getLocations(elements);
		for (int i = 1; i < locations.size(); i++) {
			if (locations.get(i).y != locations.get(0).y) {
				StringBuilder message = new StringBuilder("��߽����У��ʧ��:\n");
				for (int j = 0; j < locations.size(); j++) {
					message.append(elements.get(j).getComment() + "�����߽�λ��:"
							+ locations.get(j).y + "\n");
				}
				throw new SKFailedError(message.toString());
			}
		}
		logger.info("��߽�У��ɹ�!");
	}

	/**
	 * У���Ԫ���б��Ƿ��ұ߽����
	 * 
	 * @param elements
	 *            ��У���Ԫ��
	 * */
	public void assertRightAlign(ArrayList<Element> elements) {
		ArrayList<Point> locations = getLocations(elements);
		ArrayList<Dimension> sizes = getSizes(elements);
		for (int i = 1; i < locations.size(); i++) {
			if (locations.get(i).x + sizes.get(i).width != locations.get(0).x
					+ sizes.get(0).width) {
				StringBuilder message = new StringBuilder("�ұ߽����У��ʧ��:\n");
				for (int j = 0; j < locations.size(); j++) {
					message.append(elements.get(j).getComment() + "���ұ߽�λ��:"
							+ locations.get(j).x + sizes.get(j).width + "\n");
				}
				throw new SKFailedError(message.toString());
			}
		}
		logger.info("�ұ߽�У��ɹ�!");
	}

	/**
	 * У���Ԫ���б��Ƿ��±߽����
	 * 
	 * @param elements
	 *            ��У���Ԫ��
	 * */
	public void assertBottomAlign(ArrayList<Element> elements) {
		ArrayList<Point> locations = getLocations(elements);
		ArrayList<Dimension> sizes = getSizes(elements);
		for (int i = 1; i < locations.size(); i++) {
			if (locations.get(i).y + sizes.get(i).height != locations.get(0).y
					+ sizes.get(0).height) {
				StringBuilder message = new StringBuilder("�±߽����У��ʧ��:\n");
				for (int j = 0; j < locations.size(); j++) {
					message.append(elements.get(j).getComment() + "���±߽�λ��:"
							+ locations.get(j).y + sizes.get(j).height + "\n");
				}
				throw new SKFailedError(message.toString());
			}
		}
		logger.info("�±߽�У��ɹ�!");
	}

	/**
	 * �Ƚ�Ԫ�ص�ǰ��ɫ
	 * */
	public void assertColorEquals(ArrayList<Element> elements) {
		ArrayList<String> colors = new ArrayList<String>();
		for (Element element : elements) {
			colors.add(element.getCSSValue("color"));
		}
		StringBuilder message = new StringBuilder();
		if (colors.get(0) == null) {
			throw new SKFailedError(elements.get(0).getComment()
					+ "color���Ի�ȡ����~");
		}
		for (int i = 0; i < colors.size(); i++) {
			if (!colors.get(i).equalsIgnoreCase(colors.get(0))) {
				for (int j = 0; j < colors.size(); j++) {
					message.append(elements.get(j).getComment() + "����ɫ:"
							+ colors.get(j) + "\n");
				}
				throw new SKFailedError(message.toString());
			}
		}
		logger.info("��ɫУ��ɹ�~!");
	}

	/**
	 * У��Ԫ�ص����ϽǺ�������ε���
	 * */
	public void assertHorizonBigger(ArrayList<Element> elements) {
		ArrayList<Point> locations = getLocations(elements);
		StringBuilder message = new StringBuilder();
		for (int i = 1; i < locations.size(); i++) {
			if (locations.get(i).x < locations.get(i - 1).x) {
				message.append("Ԫ�غ�������ε���У��ʧ��!\n");
				for (int j = 0; j < locations.size(); j++) {
					message.append(elements.get(j).getComment() + "�ĺ����Ϊ:"
							+ locations.get(j).x + "\n");
				}
				throw new SKFailedError(message.toString());
			}
		}
		logger.info("Ԫ�غ�������ε���У��ɹ�~!");
	}

	/**
	 * У��Ԫ�ص����ϽǺ�������εݼ�
	 * */
	public void assertHorizonSmaller(ArrayList<Element> elements) {
		ArrayList<Point> locations = getLocations(elements);
		StringBuilder message = new StringBuilder();
		for (int i = 1; i < locations.size(); i++) {
			if (locations.get(i).x > locations.get(i - 1).x) {
				message.append("Ԫ�غ�������εݼ�У��ʧ��!\n");
				for (int j = 0; j < locations.size(); j++) {
					message.append(elements.get(j).getComment() + "�ĺ����Ϊ:"
							+ locations.get(j).x + "\n");
				}
				throw new SKFailedError(message.toString());
			}
		}
		logger.info("Ԫ�غ�������εݼ�У��ɹ�~!");
	}

	/**
	 * У��Ԫ�ص����Ͻ���������ε���
	 * */
	public void assertVerticalBigger(ArrayList<Element> elements) {
		ArrayList<Point> locations = getLocations(elements);
		StringBuilder message = new StringBuilder();
		for (int i = 1; i < locations.size(); i++) {
			if (locations.get(i).y < locations.get(i - 1).y) {
				message.append("Ԫ�غ�������ε���У��ʧ��!\n");
				for (int j = 0; j < locations.size(); j++) {
					message.append(elements.get(j).getComment() + "�������Ϊ:"
							+ locations.get(j).y + "\n");
				}
				throw new SKFailedError(message.toString());
			}
		}
		logger.info("Ԫ�غ�������ε���У��ɹ�~!");
	}

	/**
	 * У��Ԫ�ص����Ͻ���������εݼ�
	 * */
	public void assertVerticalSmaller(ArrayList<Element> elements) {
		ArrayList<Point> locations = getLocations(elements);
		StringBuilder message = new StringBuilder();
		for (int i = 1; i < locations.size(); i++) {
			if (locations.get(i).y > locations.get(i - 1).y) {
				message.append("Ԫ�غ�������εݼ�У��ʧ��!\n");
				for (int j = 0; j < locations.size(); j++) {
					message.append(elements.get(j).getComment() + "�������Ϊ:"
							+ locations.get(j).y + "\n");
				}
				throw new SKFailedError(message.toString());
			}
		}
		logger.info("Ԫ�غ�������εݼ�У��ɹ�~!");
	}

	/**
	 * У�鱾���ļ��еĶ�Ӧ��css����������������õ���css�����Ƿ�һ�£��������������������Ϊ�
	 * ���У�飬��ֱ�ӷ��أ������쳣
	 * */
	public void assertCssValue(Element element, String cssKey) {
		Properties localProperties = getCSSValueFromLocal(element);
		if (element instanceof Image) {
			if (!SKPropertiesTool.getBoolean(cssImgPropertiesConfig, cssKey)) {
				logger.warn(cssKey
						+ "�������в���У��,�ڱ��ص�css�����ļ���û�и�������Ϣ");
				return;
			}
			String engineCssValue = getCssValue(element, cssKey);
			String localCssValue = SKPropertiesTool.getValue(localProperties,
					cssKey);
			SKSimpleCheckTool.assertEqual(engineCssValue, localCssValue);
		} else {
			if (!SKPropertiesTool.getBoolean(cssCommanPropertiesConfig, cssKey)) {
				logger.warn(cssKey
						+ "�������в���У��,�ڱ��ص�css�����ļ���û�и�������Ϣ");
				return;
			}
			String engineCssValue = getCssValue(element, cssKey);
			String localCssValue = SKPropertiesTool.getValue(localProperties,
					cssKey);
			SKSimpleCheckTool.assertEqual(engineCssValue, localCssValue);
		}
	}

	/**
	 * У���Ԫ����������ֵ
	 * */
	public void assertAllCssValues(Element element) {
		Properties localProperties = getCSSValueFromLocal(element);
		Properties engineProperties = getCssValuesFromEngine(element);
		// HolmosReflectCheck.assertEquals(localProperties, engineProperties,
		// HolmosRefectionComparatorMode.IGNORE_COLLECTION_ORDER);
	}

	/**
	 * У��Ԫ�صĴ�С�����Ƿ���ͬ
	 * */
	public void assertSizesEquals(ArrayList<Element> elements) {
		ArrayList<Dimension> sizes = getSizes(elements);
		StringBuilder message = new StringBuilder();
		for (int i = 1; i < sizes.size(); i++) {
			if (!sizes.get(i).equals(sizes.get(0))) {
				message.append("Ԫ�ش�СУ��ʧ��:\n");
				for (int j = 0; j < sizes.size(); j++) {
					message.append(elements.get(j).getComment() + "��ССΪ:"
							+ sizes.get(j).toString());
				}
				logger.error(message);
				throw new SKFailedError(message.toString());
			}
		}
		message.append("Ԫ�ش�СУ��ɹ�!");
	}
}
